//
// Created by 86183 on 2022/11/10.
//

/* 小练习 */

#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#define OFFSETOF(structName, memberName) ((char *)&((structName).memberName) - (char *)&(structName))
#define T_OFFSETOF(type, name) ((size_t)&(((type *)0) -> name)) //假设结构体位于 0 地址处
#define SWAP_BIT(x) ((x) = ((((x) & 0x55555555) << 1) + (((x) & 0xaaaaaaaa) >> 1)))

enum State
{
    VALID,
    INVALID
};

struct S
{
    int a;
    char c;
    double d;
};

enum State s = INVALID;

int my_atoi(const char *str)
{
    //空指针
    assert(str);
    int flag = 0;

    //空字符串
    if (*str == '\0')
    {
        return 0;
    }

    // '+'  '-'
    if (*str == '+')
    {
        flag = 1;
        str++;
    }
    else if (*str == '-')
    {
        flag = -1;
        str++;
    }

    //非法字符
    long long ret = 0;
    while (*str)
    {
        if (isdigit(*str))
        {
            ret = ret * 10 + flag * (*str - '0');
            if (ret > INT_MAX || ret < INT_MIN)
            {
                return (int) ret;
            }
        }
        else
        {
            return (int) ret;
        }
        str++;
    }
    if (*str == '\0')
    {
        s = VALID;
    }
    return (int) ret;
}

int main()
{
    //模拟实现 atoi
    {
        int ret = my_atoi("-1234444444444444444444444444444444");
        if (s == INVALID)
        {
            printf("非法转换：%d\n", ret);
        }
        else
        {
            printf("合法转换：%d\n", ret);
        }
    }

    //模拟实现宏 offsetof
    {
        struct S s0 = { 0 };
        int ret = OFFSETOF(s0, d);
        printf("%d\n", ret);
        int ret0 = T_OFFSETOF(struct S, d);
        printf("%d\n", ret0);
    }

    //写一个宏，将一个整数的二进制位的奇数位和偶数位交换
    {
        int a = 5;
        SWAP_BIT(a);
        //原理：先提取出奇数位，向左移动一位，在提取出偶数位，向右移动一位，再把这两个相加
        //提取奇数位：按位与 0x55555555    提取偶数位：按位与 0xaaaaaaaa
        printf("%d\n", a);// 10
    }

    return 0;
}

